<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas-circle-animation</title>
</head>
<style>
    body {
        margin: 0;
    }
    .canvas {
        border: 1px solid #333333;
    }
</style>
<body>
    <div class="app">
        <canvas class="canvas"></canvas>
    </div>
    <script>
        let screenWidth = window.innerWidth;
        let screenHeight = window.innerHeight;

        const canvas = document.querySelector('.canvas');
        canvas.width = screenWidth;
        canvas.height = screenHeight;
        const context = canvas.getContext('2d');

        const mouse = {
            x: undefined,
            y: undefined,
        }

        const maxRadius = 40;

        function moveAction(event) {
            mouse.x = event.x;
            mouse.y = event.y;
        }
        window.addEventListener('mousemove', moveAction, false);
        window.addEventListener('touchmove', moveAction, false);

        window.addEventListener('resize', () => {
            screenWidth = window.innerWidth;
            screenHeight = window.innerHeight;
            canvas.width = screenWidth;
            canvas.height = screenHeight;
            init();
        }, false);

        const colors = ['#333333', '#666666', '#999999', '#1c926c', '#e8a249', '#49d2e8'];

        function Circle (x, y, dx, dy, radius) {
            this.x = x;
            this.y = y;
            this.dx = dx;
            this.dy = dy;
            this.radius = radius;
            this.minRadius = radius;
            this.color = colors[Math.floor(Math.random() * colors.length)];
            
            this.draw = () => {
                context.strokeStyle = this.color;
                context.fillStyle = this.color;
                context.beginPath();
                context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
                context.stroke();
                context.fill();
            }

            this.update = () => {
                this.x += this.dx;
                this.y += this.dy;
                if (this.x + this.radius > screenWidth || this.x - this.radius < 0) {
                    this.dx = -this.dx;
                }
                if (this.y + this.radius > screenHeight || this.y - this.radius < 0) {
                    this.dy = -this.dy;
                }
                if (mouse.x - this.x < 50 && mouse.x - this.x > -50 && mouse.y - this.y < 50 && mouse.y - this.y > -50) {
                    if (this.radius < maxRadius) {
                        this.radius += 1;
                    }
                } else {
                    if (this.radius > this.minRadius) {
                        this.radius -= 1;
                    }
                }
            }
        }

        const circleArray = [];

        function init() {

            circleArray.length = 0;

            for(let i = 0; i < 1000; i++) {
                let radius = (Math.random() + 0.5) * 3 + 1;
                let x = Math.random() * (screenWidth - radius * 2) + radius;
                let y = Math.random() * (screenHeight - radius * 2) + radius;
                let dx = (Math.random() - 0.5) * 2;
                let dy = (Math.random() - 0.5) * 2;
                const circle = new Circle(x, y, dx, dy, radius);
                circleArray.push(circle);
            }
        }

        init();

        function animation () {
            requestAnimationFrame(animation)

            context.clearRect(0, 0, screenWidth, screenHeight);

            circleArray.forEach(circle => {
                circle.draw();
                circle.update();
            })
        }

        animation();

    </script>
</body>
</html>